package com.fingard.dsp.bank.directbank.nnbill02;

import com.alibaba.fastjson.JSON;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.nnbill01.Base64Binrary;
import com.fingard.dsp.bank.directbank.spdb01.authforrec.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionParams;

import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.*;

import static org.apache.axis.transport.http.HTTPTransport.URL;

/**
 * Created by shenqi on 2019/7/26.
 */
public class NNBill02Base extends DirectBase {
    /**
     * 去掉map中 value 为空的数据
     */
    public static Map<String,Object> removeMapEmptyValue(Map<String,Object> paramMap){
        Set<String> set = paramMap.keySet();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String str = it.next();
            if(StringUtils.isEmpty(paramMap.get(str))){
                paramMap.remove(str);
                set = paramMap.keySet();
                it = set.iterator();
            }
        }
        return paramMap;
    }
    /**
     * 将MAP转换为post请求串
     * @return
     */
    public String convertMapToStr(Map<String,Object> params) {
        String reqStr = "";

        for (String key : params.keySet()) {
            if (!params.get(key).equals("")) {
                if (reqStr.length() > 0) {
                    reqStr += "&";
                }

                reqStr += key + "=" + params.get(key);
            }
        }

        return reqStr;
    }
    public static Map<String,String> convertToMap(String srcStr) {
        Map<String,String> params = new HashMap<String,String>();

        String[] nodes = srcStr.split("&");
        for (String node : nodes) {
            int index = node.indexOf("=");

            String key = node.substring(0, index);
            String value = node.substring(index+1);

            params.put(key, value);
        }

        return params;
    }
    public String sign(Map<String, Object> map,String key) throws Exception{
        try{
            map = removeMapEmptyValue(map);
            List<String> paramNames = new ArrayList<String>(map.keySet());
            Collections.sort(paramNames);
            StringBuilder sb = new StringBuilder();
            for (String paramName : paramNames) {
                sb.append(paramName).append("=").append(map.get(paramName)).append("&");
            }
            sb.append("key=").append(key);
            WriteBankLogLn("加密前拼接串："+sb.toString());
            // 进行MD5摘要
            return DigestUtils.md5Hex(sb.toString()).toUpperCase();
        }catch (Exception ex) {
            ex.printStackTrace();
            throw ex;
        }

    }

    protected String[] sendToBank(Map<String, Object> reqmap,String url) throws Exception {
        String[] retStr = new String[]{"",""};
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, null);
        SSLContext.setDefault(sslContext);
        HttpClient httpClient = new HttpClient();
        PostMethod postMethod = new PostMethod(url);
        httpClient.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 10000);
        httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT, 10000);
        // 构建消息实体
        StringRequestEntity requestEntity = new StringRequestEntity(JSON.toJSONString(reqmap), "application/json", "UTF-8");
        postMethod.setRequestEntity(requestEntity);
        // 发送Json格式的数据请求
        int result = httpClient.executeMethod(postMethod);

        if (HttpStatus.SC_OK != result) {
            retStr[0]="MessageHandlerService sendMessage fail";
        } else {
            retStr[1]=postMethod.getResponseBodyAsString();
            WriteBankLogStep3(retStr[1]);
        }

        return retStr;
    }
    /**
     * @param data 被签名的原数据字节数组，xml去掉signData节点。
     * @param signData 签名字节数组。
     * @param certFile X.509标准的证书文件。
     * @return 如果验签通过，就返回true
     * @throws RuntimeException
     */
    public static boolean veriSign(byte[] data, byte[] signData, String certFile) throws RuntimeException{
        InputStream is = null;
        try {
            //加载公钥
            is = new FileInputStream(certFile);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            Certificate cert = cf.generateCertificate(is);
            PublicKey publicKey = cert.getPublicKey();
            Signature sig = Signature.getInstance("SHA1WithRSA");
            byte[] signed = Base64Binrary.decodeBase64Binrary(new
                    String(signData));
            sig.initVerify(publicKey);
            sig.update(data);
            return sig.verify(signed);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (is != null) {
                try{
                    is.close();
                }catch(Exception e){
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
    }
}
